/*
 * @Author: askMeWhy
 * @Date:   2018-07-05 09:47:04
 * @Last Modified by: AskMeWhy
 * @Last Modified time: 2021-01-15 14:39:27
 */
import { merge, isObject, ajax } from "../utils/index";
import API_CONFIG from './api.js';
import { API_DEFAULT_CONFIG } from './config.js';

/**
 * 接口类
 * 向外暴露 server 和 info 属性
 *
 * 调用方式
 * import Api from '@/services'
 *
 * Api.server['namespace/name']()
 * 该属性使用API_CONFIG里的配置属性封装了请求方式 最终返回一个Promise
 * Api.info['namespace/name']
 * 该属性会直接返回API_CONFIG里的配置属性，并每个配置项会多返回completePath
 * completePath: 是baseUrl加上配置的path的完整路径
 *
 */
const wxApp = getApp();
class ServiceInstance {
    constructor(options) {
        this.server = {};
        this.info = {};
        this.baseUrl = options.BaseURL || '';
        this.apiBuild(options);
    }
    apiBuild({
        BaseURL = '',
        MockURL = '',
        MockModel = {},
        config = {}
    }) {
        let _self = this;
        Object.keys(config).map(once => {
            const cur = config[once];
            const { name, params, method, path, namespace, mock, headers, setCommonParam } = cur;
            let apiName = `${namespace ? namespace + '/' : ''}${name}`;
            let url = '';
            if (mock !== void 0 && mock.open) {
                url = `${MockModel.url}${mock.path || path}`;
            } else {
                url = `${BaseURL}${path}`;
            }
            
            Object.defineProperty(this.server, apiName, {
                value(_params = { data: {}, headers: {}, params: {}, loader: true }) {
                    let _p = _params.data;
                    if(isObject(_params.data)){
                        _p = merge(true, {}, params, _params.data || {});
                    }
                    if(Array.isArray(_params.data)){
                        _p = merge(true, [], params, _params.data || []);
                    }
                    let _o = merge(true, {}, headers || {}, _params.headers || {});
                    let _url = url;
                    if (_self.hasUrlParam(_url)) {
                        _url = _self.buildUrlParam(url, _params.params, apiName);
                    }
                    // console.log(wxApp.user.userInfo);
             

                    if (setCommonParam) {
                        let _token = (mock && mock.open) ? (MockModel.token || '') : (wxApp.user.token || '');
                        if(_token){
                            _o.Authorization = "Bearer " + _token;
                        }

                        let userInfo =  wxApp.user.userInfo;
                        // console.log(userInfo);
                         // cityCode  departmentId  governmentIds(不要s取第一个)  orgCategoryId
                         
                        _o.cityCode = userInfo.cityCode;
                        _o.departmentId = userInfo.departmentId;
                        _o.governmentId = userInfo.governmentId;
                        _o.orgCategoryId = userInfo.orgCategoryId;
                    }
                 
                    // console.log(_o);
                   
                    return ajax({
                        method: method,
                        url: _url,
                        // data: _self.buildEmptyData(_p),
                        data: _p,
                        loader: _params.loader === void 0 ? true : _params.loader,
                        headers: {
                            ..._o,
                        },
                        before: opt => {
                            if(opt.loader){
                                wxApp.loader(true);
                            }
                            return Promise.resolve(true);
                        },
                        after: (opt, res) => {
                            // console.log(res)
                            // console.log("====处理=====");
                                // console.log(_url);
                   
                            if (opt.loader) {
                                let code = res.data.code;
                                //处理一下 有些需要显示toast的情况
                                const ifShow =  _self.checkIfHandleUrl(_url);
                                // console.log(ifShow)
                                wxApp.loader(false,ifShow == true ? 1 : code);
                            }

                            if (res.statusCode === 200) {

                                return Promise.resolve(res);
                            } else {
                                wx.askShowToastEx({
                                    mask: true,
                                    title: res.msg || res.message,
                                    icon: "none",
                                    duration: 2000,
                                    cancel: () => {
                                        if (res && res.statusCode === 401) {
                                            wxApp.logout("redirect-login");
                                        }
                                    },
                                });
                                return Promise.reject(res);
                            }
                        }
                    });
                }
            });
            Object.defineProperty(this.info, apiName, {
                value: {
                    completePath: url,
                    ...cur
                }
            });
        });
    }
    hasUrlParam(url) {
        let reg = /\/:\w*/g;
        return url.match(reg) !== null;
    }
    buildUrlParam(url, params, apiName) {
        console.log("---");
        console.log(params);
        if (params === void 0) {
            throw Error(`请传入"${apiName}"已配置的params`);
        }
        let reg = /\/:\w*/g;
        let u = url.replace(reg, function(p, p2) {
            let key = p.substring(2);
            if (params[key] === void 0) {
                throw Error(`"${apiName}"必须包含已配置的"${key}"`);
            }
            return '/' + params[key];
        });
        return u;
    }
    buildEmptyData(data){
        const emptyList = [null, undefined, ""];
        let _data = Array.isArray(data) ? []:{}
        for (const key in data) {
            if (data.hasOwnProperty(key)) {
                const cur = data[key];
                // if (Array.isArray(cur)) {
                //     if(cur.length > 0){
                //         const _res = this.buildEmptyData(cur);
                //         if (_res.length > 0){
                //             _data[key] = _res;
                //         }
                //     }
                // }else if (isObject(cur)) {
                //     if(!isEmptyObject(cur)){
                //         const _res = this.buildEmptyData(cur);
                //         if (!isEmptyObject(_res)) {
                //             _data[key] = _res;
                //         }
                //     }
                // }else{
                    if(!emptyList.includes(cur)){
                        _data[key] = cur;
                    }
                // }
            }
        }
        return _data;
    }
    checkIfHandleUrl(requestUrl){
        const arr = ["user/bind","user/editPassword/self","/user/findPassword"];
        let value = false;
        arr.forEach(element => {
            // console.log(element);
            if(requestUrl.indexOf(element)>=0){
                value = true;
            }
        });
        return value;
    }
}

export default new ServiceInstance({
    config: API_CONFIG,
    ...API_DEFAULT_CONFIG
});
